home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Magazine / Online / QMail / source / qmail-pw2u.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-05  |  8.7 KB  |  309 lines

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include "substdio.h"
  4. #include "readwrite.h"
  5. #include "subfd.h"
  6. #include "sgetopt.h"
  7. #include "control.h"
  8. #include "constmap.h"
  9. #include "stralloc.h"
  10. #include "fmt.h"
  11. #include "str.h"
  12. #include "scan.h"
  13. #include "open.h"
  14. #include "error.h"
  15. #include "getln.h"
  16. #include "auto_break.h"
  17. #include "auto_qmail.h"
  18. #include "auto_usera.h"
  19.  
  20. void die_chdir()
  21. {
  22.   substdio_putsflush(subfderr,"qmail-pw2u: fatal: unable to chdir\n");
  23.   _exit(111);
  24. }
  25. void die_nomem()
  26. {
  27.   substdio_putsflush(subfderr,"qmail-pw2u: fatal: out of memory\n");
  28.   _exit(111);
  29. }
  30. void die_read()
  31. {
  32.   substdio_putsflush(subfderr,"qmail-pw2u: fatal: unable to read input\n");
  33.   _exit(111);
  34. }
  35. void die_write()
  36. {
  37.   substdio_putsflush(subfderr,"qmail-pw2u: fatal: unable to write output\n");
  38.   _exit(111);
  39. }
  40. void die_control()
  41. {
  42.   substdio_putsflush(subfderr,"qmail-pw2u: fatal: unable to read controls\n");
  43.   _exit(111);
  44. }
  45. void die_alias()
  46. {
  47.   substdio_puts(subfderr,"qmail-pw2u: fatal: unable to find ");
  48.   substdio_puts(subfderr,auto_usera);
  49.   substdio_puts(subfderr," user\n");
  50.   substdio_flush(subfderr);
  51.   _exit(111);
  52. }
  53. void die_home(fn) char *fn;
  54. {
  55.   substdio_puts(subfderr,"qmail-pw2u: fatal: unable to stat ");
  56.   substdio_puts(subfderr,fn);
  57.   substdio_puts(subfderr,"\n");
  58.   substdio_flush(subfderr);
  59.   _exit(111);
  60. }
  61. void die_user(s,len) char *s; unsigned int len;
  62. {
  63.   substdio_puts(subfderr,"qmail-pw2u: fatal: unable to find ");
  64.   substdio_put(subfderr,s,len);
  65.   substdio_puts(subfderr," user for subuser\n");
  66.   substdio_flush(subfderr);
  67.   _exit(111);
  68. }
  69.  
  70. int flagalias = 0;
  71. int flagnoupper = 1;
  72. int homestrategy = 2;
  73. /* 2: skip if home does not exist; skip if home is not owned by user */
  74. /* 1: stop if home does not exist; skip if home is not owned by user */
  75. /* 0: don't worry about home */
  76.  
  77. int okincl; stralloc incl = {0}; struct constmap mapincl;
  78. int okexcl; stralloc excl = {0}; struct constmap mapexcl;
  79. int okmana; stralloc mana = {0}; struct constmap mapmana;
  80.  
  81. stralloc allusers = {0}; struct constmap mapuser;
  82.  
  83. stralloc uugh = {0};
  84. stralloc user = {0};
  85. stralloc uidstr = {0};
  86. stralloc gidstr = {0};
  87. stralloc home = {0};
  88. unsigned long uid;
  89.  
  90. stralloc line = {0};
  91.  
  92. void doaccount()
  93. {
  94.   struct stat st;
  95.   int i;
  96.   char *mailnames;
  97.   char *x;
  98.   unsigned int xlen;
  99.  
  100.   if (byte_chr(line.s,line.len,'\0') < line.len) return;
  101.  
  102.   x = line.s; xlen = line.len; i = byte_chr(x,xlen,'|'); if (i == xlen) return;
  103.   if (!stralloc_copyb(&user,x,i)) die_nomem();
  104.   if (!stralloc_0(&user)) die_nomem();
  105.   ++i; x += i; xlen -= i; i = byte_chr(x,xlen,'|'); if (i == xlen) return;
  106.   ++i; x += i; xlen -= i; i = byte_chr(x,xlen,'|'); if (i == xlen) return;
  107.   if (!stralloc_copyb(&uidstr,x,i)) die_nomem();
  108.   if (!stralloc_0(&uidstr)) die_nomem();
  109.   scan_ulong(uidstr.s,&uid);
  110.   ++i; x += i; xlen -= i; i = byte_chr(x,xlen,'|'); if (i == xlen) return;
  111.   if (!stralloc_copyb(&gidstr,x,i)) die_nomem();
  112.   if (!stralloc_0(&gidstr)) die_nomem();
  113.   ++i; x += i; xlen -= i; i = byte_chr(x,xlen,'|'); if (i == xlen) return;
  114.   ++i; x += i; xlen -= i; i = byte_chr(x,xlen,'|'); if (i == xlen) return;
  115.   if (!stralloc_copyb(&home,x,i)) die_nomem();
  116.   if (!stralloc_0(&home)) die_nomem();
  117.  
  118.   if (!uid) return;
  119.   if (flagnoupper)
  120.     for (i = 0;i < user.len;++i)
  121.       if ((user.s[i] >= 'A') && (user.s[i] <= 'Z'))
  122.     return;
  123.   if (okincl)
  124.     if (!constmap(&mapincl,user.s,user.len - 1))
  125.       return;
  126.   if (okexcl)
  127.     if (constmap(&mapexcl,user.s,user.len - 1))
  128.       return;
  129.   if (homestrategy) {
  130.     if (stat(home.s,&st) == -1) {
  131.       if (errno != error_noent) die_home(home.s);
  132.       if (homestrategy == 1) die_home(home.s);
  133.       return;
  134.     }
  135.     if (st.st_uid != uid) return;
  136.   }
  137.  
  138.   if (!stralloc_copys(&uugh,":")) die_nomem();
  139.   if (!stralloc_cats(&uugh,user.s)) die_nomem();
  140.   if (!stralloc_cats(&uugh,":")) die_nomem();
  141.   if (!stralloc_cats(&uugh,uidstr.s)) die_nomem();
  142.   if (!stralloc_cats(&uugh,":")) die_nomem();
  143.   if (!stralloc_cats(&uugh,gidstr.s)) die_nomem();
  144.   if (!stralloc_cats(&uugh,":")) die_nomem();
  145.   if (!stralloc_cats(&uugh,home.s)) die_nomem();
  146.   if (!stralloc_cats(&uugh,":")) die_nomem();
  147.  
  148.   /* XXX: avoid recording in allusers unless sub actually needs it */
  149.   if (!stralloc_cats(&allusers,user.s)) die_nomem();
  150.   if (!stralloc_cats(&allusers,":")) die_nomem();
  151.   if (!stralloc_catb(&allusers,uugh.s,uugh.len)) die_nomem();
  152.   if (!stralloc_0(&allusers)) die_nomem();
  153.  
  154.   if (str_equal(user.s,auto_usera)) {
  155.     if (substdio_puts(subfdout,"+") == -1) die_write();
  156.     if (substdio_put(subfdout,uugh.s,uugh.len) == -1) die_write();
  157.     if (substdio_puts(subfdout,"-::\n") == -1) die_write();
  158.     flagalias = 1;
  159.   }
  160.  
  161.   mailnames = 0;
  162.   if (okmana)
  163.     mailnames = constmap(&mapmana,user.s,user.len - 1);
  164.   if (!mailnames)
  165.     mailnames = user.s;
  166.  
  167.   for (;;) {
  168.     while (*mailnames == '|') ++mailnames;
  169.     if (!*mailnames) break;
  170.  
  171.     i = str_chr(mailnames,'|');
  172.  
  173.     if (substdio_puts(subfdout,"=") == -1) die_write();
  174.     if (substdio_put(subfdout,mailnames,i) == -1) die_write();
  175.     if (substdio_put(subfdout,uugh.s,uugh.len) == -1) die_write();
  176.     if (substdio_puts(subfdout,"::\n") == -1) die_write();
  177.   
  178.     if (*auto_break) {
  179.       if (substdio_puts(subfdout,"+") == -1) die_write();
  180.       if (substdio_put(subfdout,mailnames,i) == -1) die_write();
  181.       if (substdio_put(subfdout,auto_break,1) == -1) die_write();
  182.       if (substdio_put(subfdout,uugh.s,uugh.len) == -1) die_write();
  183.       if (substdio_puts(subfdout,"-::\n") == -1) die_write();
  184.     }
  185.  
  186.     mailnames += i;
  187.   }
  188. }
  189.  
  190. stralloc sub = {0};
  191.  
  192. void dosubuser()
  193. {
  194.   int i;
  195.   char *x;
  196.   unsigned int xlen;
  197.   char *uugh;
  198.  
  199.   x = line.s; xlen = line.len; i = byte_chr(x,xlen,'|'); if (i == xlen) return;
  200.   if (!stralloc_copyb(&sub,x,i)) die_nomem();
  201.   ++i; x += i; xlen -= i; i = byte_chr(x,xlen,'|'); if (i == xlen) return;
  202.   uugh = constmap(&mapuser,x,i);
  203.   if (!uugh) die_user(x,i);
  204.   ++i; x += i; xlen -= i; i = byte_chr(x,xlen,'|'); if (i == xlen) return;
  205.  
  206.   if (substdio_puts(subfdout,"=") == -1) die_write();
  207.   if (substdio_put(subfdout,sub.s,sub.len) == -1) die_write();
  208.   if (substdio_puts(subfdout,uugh) == -1) die_write();
  209.   if (substdio_puts(subfdout,"-:") == -1) die_write();
  210.   if (substdio_put(subfdout,x,i) == -1) die_write();
  211.   if (substdio_puts(subfdout,":\n") == -1) die_write();
  212.  
  213.   if (*auto_break) {
  214.     if (substdio_puts(subfdout,"+") == -1) die_write();
  215.     if (substdio_put(subfdout,sub.s,sub.len) == -1) die_write();
  216.     if (substdio_put(subfdout,auto_break,1) == -1) die_write();
  217.     if (substdio_puts(subfdout,uugh) == -1) die_write();
  218.     if (substdio_puts(subfdout,"-:") == -1) die_write();
  219.     if (substdio_put(subfdout,x,i) == -1) die_write();
  220.     if (substdio_puts(subfdout,"-:\n") == -1) die_write();
  221.   }
  222. }
  223.  
  224. int fd;
  225. substdio ss;
  226. char ssbuf[SUBSTDIO_INSIZE];
  227.  
  228. void main(argc,argv)
  229. int argc;
  230. char **argv;
  231. {
  232.   int opt;
  233.   int match;
  234.  
  235.   while ((opt = getopt(argc,argv,"ohHuUc:C")) != opteof)
  236.     switch(opt) {
  237.       case 'o': homestrategy = 2; break;
  238.       case 'h': homestrategy = 1; break;
  239.       case 'H': homestrategy = 0; break;
  240.       case 'u': flagnoupper = 0; break;
  241.       case 'U': flagnoupper = 1; break;
  242.       case 'c': *auto_break = *optarg; break;
  243.       case 'C': *auto_break = 0; break;
  244.       case '?':
  245.       default:
  246.     _exit(100);
  247.     }
  248.  
  249.   if (chdir(auto_qmail) == -1) die_chdir();
  250.  
  251.   /* no need for control_init() */
  252.  
  253.   okincl = control_readfile(&incl,"users/include",0);
  254.   if (okincl == -1) die_control();
  255.   if (okincl) if (!constmap_init(&mapincl,incl.s,incl.len,0)) die_nomem();
  256.  
  257.   okexcl = control_readfile(&excl,"users/exclude",0);
  258.   if (okexcl == -1) die_control();
  259.   if (okexcl) if (!constmap_init(&mapexcl,excl.s,excl.len,0)) die_nomem();
  260.  
  261.   okmana = control_readfile(&mana,"users/mailnames",0);
  262.   if (okmana == -1) die_control();
  263.   if (okmana) if (!constmap_init(&mapmana,mana.s,mana.len,1)) die_nomem();
  264.  
  265.   if (!stralloc_copys(&allusers,"")) die_nomem();
  266.  
  267.   for (;;) {
  268.     if (getln(subfdin,&line,&match,'\n') == -1) die_read();
  269.     doaccount();
  270.     if (!match) break;
  271.   }
  272.   if (!flagalias) die_alias();
  273.  
  274.   fd = open_read("users/subusers");
  275.   if (fd == -1) {
  276.     if (errno != error_noent) die_control();
  277.   }
  278.   else {
  279.     substdio_fdbuf(&ss,read,fd,ssbuf,sizeof(ssbuf));
  280.  
  281.     if (!constmap_init(&mapuser,allusers.s,allusers.len,1)) die_nomem();
  282.  
  283.     for (;;) {
  284.       if (getln(&ss,&line,&match,'\n') == -1) die_read();
  285.       dosubuser();
  286.       if (!match) break;
  287.     }
  288.  
  289.     close(fd);
  290.   }
  291.  
  292.   fd = open_read("users/append");
  293.   if (fd == -1) {
  294.     if (errno != error_noent) die_control();
  295.   }
  296.   else {
  297.     substdio_fdbuf(&ss,read,fd,ssbuf,sizeof(ssbuf));
  298.     for (;;) {
  299.       if (getln(&ss,&line,&match,'\n') == -1) die_read();
  300.       if (substdio_put(subfdout,line.s,line.len) == -1) die_write();
  301.       if (!match) break;
  302.     }
  303.   }
  304.  
  305.   if (substdio_puts(subfdout,".\n") == -1) die_write();
  306.   if (substdio_flush(subfdout) == -1) die_write();
  307.   _exit(0);
  308. }
  309.